/**
 * 短信云函数（重构版，对接腾讯云短信）
 */

const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

const db = cloud.database()
const _ = db.command

const config = require('./config/config')
const TencentSmsClient = require('./utils/smsClient')

// 实例化短信客户端
let smsClient = null
if (config[config.env].sendRealSms) {
  smsClient = new TencentSmsClient()
}

/**
 * 生成6位数字验证码
 */
function generateCode() {
  return Math.floor(100000 + Math.random() * 900000).toString()
}

/**
 * 验证手机号格式
 */
function validatePhone(phone) {
  const phoneReg = /^[1][3,4,5,7,8,9][0-9]{9}$/
  return phoneReg.test(phone)
}

/**
 * 发送短信（根据环境决定是否真实发送）
 */
async function sendSMS(phone, code) {
  const envConfig = config[config.env]

  if (envConfig.sendRealSms && smsClient) {
    // 生产环境：发送真实短信
    console.log(`[生产环境] 发送真实短信到 ${phone}`)
    return await smsClient.sendVerifyCode(phone, code)
  } else {
    // 开发环境：模拟发送
    console.log(`[开发环境] 模拟发送短信到 ${phone}，验证码：${code}`)
    console.log(`===============================`)
    console.log(`📱 手机号：${phone}`)
    console.log(`🔐 验证码：${code}`)
    console.log(`⏰ 有效期：${config.verifyCode.expireTime / 60000} 分钟`)
    console.log(`===============================`)
    
    return {
      success: true,
      message: `验证码已生成（开发环境）：${code}`
    }
  }
}

/**
 * 云函数入口
 */
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const { action, data } = event

  console.log(`[SMS] 收到请求: ${action}`, data)

  try {
    switch (action) {
      case 'sendCode':
        return await sendVerifyCode(data, wxContext)
      case 'verifyCode':
        return await verifyCode(data, wxContext)
      default:
        return {
          success: false,
          code: 400,
          message: '不支持的操作类型'
        }
    }
  } catch (error) {
    console.error('[SMS] 云函数执行错误:', error)
    return {
      success: false,
      code: 500,
      message: error.message || '服务器内部错误'
    }
  }
}

/**
 * 发送验证码
 */
async function sendVerifyCode(data, wxContext) {
  const { phone, type } = data

  // 参数验证
  if (!phone || !type) {
    return {
      success: false,
      code: 1008,
      message: '手机号和验证码类型不能为空'
    }
  }

  if (!validatePhone(phone)) {
    return {
      success: false,
      code: 1008,
      message: '请输入正确的手机号格式'
    }
  }

  if (!['login', 'register', 'reset'].includes(type)) {
    return {
      success: false,
      code: 1008,
      message: '验证码类型不正确'
    }
  }

  try {
    // 检查60秒内是否已发送过验证码
    const sixtySecondsAgo = new Date(Date.now() - config.verifyCode.sendInterval)
    const recentCodes = await db.collection('verify_codes')
      .where({
        phone: phone,
        type: type,
        createTime: _.gte(sixtySecondsAgo)
      })
      .get()

    if (recentCodes.data.length > 0) {
      const lastSendTime = new Date(recentCodes.data[0].createTime)
      const remainingSeconds = Math.ceil((config.verifyCode.sendInterval - (Date.now() - lastSendTime.getTime())) / 1000)
      
      return {
        success: false,
        code: 1009,
        message: `请${remainingSeconds}秒后再试`
      }
    }

    // 检查一天内同一手机号发送次数
    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000)
    const todayCodes = await db.collection('verify_codes')
      .where({
        phone: phone,
        createTime: _.gte(oneDayAgo)
      })
      .get()

    if (todayCodes.data.length >= config.verifyCode.dailyLimit) {
      return {
        success: false,
        code: 1010,
        message: '今日验证码发送次数已达上限'
      }
    }

    // 生成验证码
    const envConfig = config[config.env]
    const code = envConfig.sendRealSms ? generateCode() : (envConfig.mockCode || generateCode())
    const expireTime = new Date(Date.now() + config.verifyCode.expireTime)

    // 保存验证码到数据库
    await db.collection('verify_codes').add({
      data: {
        phone: phone,
        code: code,
        type: type,
        used: false,
        createTime: new Date(),
        expireTime: expireTime,
        openid: wxContext.OPENID
      }
    })

    // 发送短信
    const smsResult = await sendSMS(phone, code)

    if (!smsResult.success) {
      console.error('[SMS] 短信发送失败:', smsResult.message)
      return {
        success: false,
        code: 1011,
        message: smsResult.message || '短信发送失败，请稍后重试'
      }
    }

    // 返回结果
    const message = envConfig.sendRealSms 
      ? '验证码已发送，请注意查收' 
      : `验证码已生成：${code}（开发环境）`

    return {
      success: true,
      code: 200,
      message: message,
      data: {
        success: true,
        message: message,
        expireTime: config.verifyCode.expireTime / 1000 // 秒
      }
    }
  } catch (error) {
    console.error('[SMS] 发送验证码错误:', error)
    return {
      success: false,
      code: 500,
      message: '发送验证码失败，请重试'
    }
  }
}

/**
 * 验证验证码
 */
async function verifyCode(data, wxContext) {
  const { phone, code } = data

  if (!phone || !code) {
    return {
      success: false,
      code: 1008,
      message: '手机号和验证码不能为空'
    }
  }

  if (!validatePhone(phone)) {
    return {
      success: false,
      code: 1008,
      message: '请输入正确的手机号格式'
    }
  }

  try {
    // 查询验证码
    const codeResult = await db.collection('verify_codes')
      .where({
        phone: phone,
        code: code,
        used: false,
        expireTime: _.gte(new Date())
      })
      .get()

    if (codeResult.data.length === 0) {
      // 查询验证码是否存在但已过期
      const expiredCodeResult = await db.collection('verify_codes')
        .where({
          phone: phone,
          code: code,
          used: false
        })
        .get()

      if (expiredCodeResult.data.length > 0) {
        return {
          success: false,
          code: 1006,
          message: '验证码不正确或已过期，请重新获取'
        }
      }

      return {
        success: false,
        code: 1005,
        message: '验证码错误'
      }
    }

    // 标记验证码为已使用
    const codeRecord = codeResult.data[0]
    await db.collection('verify_codes').doc(codeRecord._id).update({
      data: {
        used: true,
        usedTime: new Date()
      }
    })

    return {
      success: true,
      code: 200,
      message: '验证码验证成功',
      data: {
        valid: true
      }
    }
  } catch (error) {
    console.error('[SMS] 验证验证码错误:', error)
    return {
      success: false,
      code: 500,
      message: '验证码验证失败'
    }
  }
}

